package cmsc427.mw5;

public class GestureGuess {

	/**
	 *  K Nearest Neighbor, K = 1.  Calculates the distance between the current sample window's
	 *  stats and each instance of the training set.  Guesses the gesture with the smallest distance.
	 *  Technically, this is a slow algorithm, but since the sample sizes are controlled, there should
	 *  be no problem running it.
	 */
	public static String checkWindow(SampleWindow sample, TrainingSet tSet){
		
		float leastDeltaX = Float.MAX_VALUE;
		float leastDeltaY = Float.MAX_VALUE;
		float leastDeltaZ = Float.MAX_VALUE;
		
		float deltaX = 0, deltaY=0, deltaZ=0;
		
		String currentGuess = "unknown";
		int trainingSetSize = tSet.getSize();
		RawTrainingValues currentTrainingValues;
		AccelerometerReading currentReading = new AccelerometerReading(0,0,0);
		
		
		//for each training example
		for(int i=0; i < trainingSetSize; i++){
			//currentDistance = 0;
			currentTrainingValues = tSet.values.get(i);
			
			deltaX = deltaY = deltaZ = 0;
			//for each reading in the sample window -- cycle through the queue
			for(int j=0; j < sample.getSampleSize()*3 - 3; j+=3){
				currentReading = sample.readingsWindow.remove();
				
				deltaX += (currentTrainingValues.values[j] - currentReading.getX()) * (currentTrainingValues.values[j] - currentReading.getX());
				deltaY += (currentTrainingValues.values[j+1] - currentReading.getY()) * (currentTrainingValues.values[j+1] - currentReading.getY());
				deltaZ += (currentTrainingValues.values[j+2] - currentReading.getZ()) * (currentTrainingValues.values[j+2] - currentReading.getZ());
				
				sample.readingsWindow.add( currentReading );
			}

			deltaX = (float)Math.sqrt( deltaX );
			deltaY = (float)Math.sqrt( deltaY );
			deltaZ = (float)Math.sqrt( deltaZ );
		
			//test +=  " c: " + currentTrainingValues.tmp.length + "\n";
			
			if(deltaX < leastDeltaX && deltaY < leastDeltaY && deltaZ < leastDeltaZ){
				leastDeltaX = deltaX;
				leastDeltaY = deltaY;
				leastDeltaZ = deltaZ;
				currentGuess = currentTrainingValues.classifier;
			}
		}
		/*
		 * --TODO Throw events here and change return type (void ?)
		 */
		if(!currentGuess.contains("nogesture") && leastDeltaX < 1000 && leastDeltaZ < 1000 && leastDeltaY < 1000){
			return currentGuess;// + "\n(" + (int)leastDeltaX + ", " + (int)leastDeltaY + ", " + (int)leastDeltaZ + ")\n";
		}
		else
		{
			return "unknown";
		}
	}
	
}

